﻿using System;
using System.Diagnostics;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;


namespace MsBuildAxTasks.Tasks
{
    /// <summary>
    /// http://technet.microsoft.com/en-us/library/aa548130.aspx
    /// </summary>
    public class AxInstall : Task
    {
        private const string dq = "\"";
        private const int ERROR_FILE_NOT_FOUND = 2;



        [Required]
        public string AxSetupPath { get; set; }

        public string AxSetupFile { get; set; }

        #region Database Parameters
        public string InstallDatabase { get; set; }
        public string DbServerType { get; set; }
        public string DbSqlDatabaseName { get; set; }
        public string DbSqlServer { get; set; }
        public string DbConnectionTimeout { get; set; }
        #endregion

        #region General Paramerts
        public string HideUI { get; set; }
        public string LogDir { get; set; }
        public string RunMode { get; set; }
        public string AcceptLicenseTerms { get; set; }
        #endregion

        #region AOS parameters
        public string InstallAOS { get; set; }
        public string AosApplicationPath { get; set; }
        public string AosInstanceName { get; set; }
        public string AosPort { get; set; }
        public string AosStart { get; set; }
        public string ApplicationInstanceName { get; set;}
        public string RemoveAos { get; set; }
        #endregion

        private void Init()
        {
            AxSetupFile = "setup.exe";

            HideUI = "1";
            AcceptLicenseTerms = "1";
            RunMode = "Custom";

            DbServerType = "0";
        }

        protected string addArgument(string parameter, string value)
        {
            string argument = "";
            if (!string.IsNullOrEmpty(value))
            {
                argument += " " + parameter + "=" + value;
            }
            return argument;
        }

        private string BuildArguments()
        {
            string argument = "";
            if (!string.IsNullOrEmpty(HideUI))
            {
                argument = argument + " HideUI=" + HideUI;
            }
            if (!string.IsNullOrEmpty(AcceptLicenseTerms))
            {
                argument = argument + " AcceptLicenseTerms=" + AcceptLicenseTerms;
            }
            if (!string.IsNullOrEmpty(RunMode))
            {
                argument = argument + " RunMode=" + RunMode;
            }
            if (!string.IsNullOrEmpty(LogDir))
            {
                argument = argument + " LogDir=" + LogDir;
            }
            if (!string.IsNullOrEmpty(InstallDatabase))
            {
                argument = argument + " InstallDatabase=" + InstallDatabase;
                if (!string.IsNullOrEmpty(DbServerType))
                {
                    argument = argument + " DbServerType=" + DbServerType;
                }
                if (!string.IsNullOrEmpty(DbSqlServer))
                {
                    argument = argument + " DbSqlServer=" + DbSqlServer;
                }
                if (string.IsNullOrEmpty(DbSqlDatabaseName))
                {
                    throw new Exception("The parameter DbSqlDatabaseName contains an invalid value");
                }
                argument = argument + " DbSqlDatabaseName=" + DbSqlDatabaseName;
            }
            if (!string.IsNullOrEmpty(RemoveAos))
            {
                return (argument + addArgument("RemoveAos", RemoveAos) + addArgument("AosInstanceName", AosInstanceName));
            }
            if (!string.IsNullOrEmpty(this.InstallAOS))
            {
                argument = ((argument + this.addArgument("InstallAOS", InstallAOS) + this.addArgument("AosInstanceName", AosInstanceName)) + this.addArgument("AosApplicationPath", "\"" + this.AosApplicationPath + "\"") + this.addArgument("ApplicationInstanceName", this.ApplicationInstanceName)) + this.addArgument("AosStart", AosStart) + addArgument("AosPort", AosPort);
            }
            return argument;
        }

        private bool processLog()
        {
            string log = "";
            return true;
            //return (log.IndexOf("ErrorLevel/ExitCode: '1'") == -1);
        }

        public override bool Execute()
        {
            Init();
            bool ok = true;
            Log.LogMessage("Arguments: {0}", this.BuildArguments());
            try
            {
                Process proc = new Process();
                proc.StartInfo.WorkingDirectory = this.AxSetupPath;
                proc.StartInfo.FileName = this.AxSetupFile;
                proc.StartInfo.Arguments = this.BuildArguments();
                proc.StartInfo.UseShellExecute = true;
                proc.Start();
                proc.WaitForExit();
                if (!this.processLog())
                {
                    Log.LogError("Ax Setup was canceled or failed.");
                    ok = false;
                }
            }
            catch (Win32Exception e)
            {
                if (ERROR_FILE_NOT_FOUND == 2)
                {
                    Log.LogError(e.Message + ". Check the path.");
                    ok = false;
                }
            }
            return ok;

        }
    }
}
